﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Windows.Media.Imaging;
using System.Diagnostics;
using System.Collections.ObjectModel;

using Res = WasaWasa.Properties.Resources;

namespace WasaWasa
{
    partial class MainWindow
    {
        public const string ApiHost = "api.wassr.jp";
        public const string ApiPictureHost = "wassr.jp";
        public const int ApiPort = 80;

        private string UserAgent;

        private ObservableCollection<LogItem> logItems;

        partial void InitializeCommonMethods()
        {
            logItems = new ObservableCollection<LogItem>();
            lstLogItems.ItemsSource = logItems;

            VersionInfoClass verinfo = new VersionInfoClass();
            UserAgent = string.Format("{0} {1}/.NET Framework {2}(3.5+)/{3}",
                verinfo.Product, verinfo.Version, Environment.Version, Environment.OSVersion.VersionString);
            AppendLogText(Res.MessageGenerateUserAgent);
            AppendLogText(UserAgent);
        }

        private bool SetWebRequestOptions(HttpWebRequest wreq)
        {
            bool ret = true;

            ret &= SetWebRequestUserAgent(wreq);
            ret &= SetWebRequestProxy(wreq);
            ret &= SetWebRequestCredentials(wreq);

            return ret;
        }

        private bool SetWebRequestUserAgent(HttpWebRequest wreq)
        {
            wreq.UserAgent = UserAgent;
            return true;
        }

        /// <summary>
        /// WebRequestにプロキシサーバーを設定します。
        /// </summary>
        /// <param name="wreq">設定するWebRequest</param>
        /// <returns>設定に成功したかどうか</returns>
        private bool SetWebRequestProxy(HttpWebRequest wreq)
        {
            try
            {
                if (def.UseProxy)
                    wreq.Proxy = def.UseSystemProxy ?
                        WebRequest.DefaultWebProxy :
                        new WebProxy(def.ProxyHost, def.ProxyPort);
                if (def.UseProxy && !def.UseSystemProxy)
                    wreq.Proxy.Credentials = string.IsNullOrEmpty(def.ProxyUserName) ?
                        new NetworkCredential(def.ProxyUserName, def.ProxyPassword) : null;
            }
            catch
            {
                AppendLogText(Res.ErrorInvalidProxySettings);
                return false;
            }
            return true;
        }

        /// <summary>
        /// WebRequestに認証情報を設定します。
        /// </summary>
        /// <param name="wreq">設定するWebRequest</param>
        /// <returns>設定に成功したかどうか</returns>
        private bool SetWebRequestCredentials(HttpWebRequest wreq)
        {
            if (def.UseBasicAuthentication && !string.IsNullOrEmpty(def.UserName) && !string.IsNullOrEmpty(def.Password))
            {
                wreq.Credentials = new NetworkCredential(def.UserName, DESStringCrypto.DecryptString(def.Password));
                return true;
            }
            else if (def.UseWassrAuthenticationAPI && !string.IsNullOrEmpty(def.UserName) && !string.IsNullOrEmpty(def.AuthenticationToken))
            {
                try
                {
                    wreq.Credentials = new NetworkCredential(def.UserName, DESStringCrypto.DecryptString(def.AuthenticationToken));
                    return true;
                }
                catch { }//TODO:Empty catch block
            }
            AppendLogText(Res.ErrorInvalidAccountSettings);
            return false;
        }

        /// <summary>
        /// アプリケーションログを追加します。
        /// </summary>
        /// <param name="str">ステータス文字列</param>
        private void AppendLogText(String msg)
        {
            Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
            {
                txtLastLogText.Text = msg;
                logItems.Add(new LogItem(msg));
            }));
        }

        private void TimeOutCallback(object state, bool timedOut)
        {
            object[] args = state as object[];
            WebRequest wreq = args[0] as WebRequest;
            string ope = args[1] as string;
            if (timedOut)
            {
                wreq.Abort();
                AppendLogText(ope + Res.ResultTimedOut);
            }
        }
    }
}
